package com.tansun.easycare.rule.table.evaluationindex.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.tansun.easycare.rule.common.rulebasebean.Action;
import com.tansun.easycare.rule.common.rulebasebean.DThen;
import com.tansun.easycare.rule.common.rulebasebean.DWhen;
import com.tansun.easycare.rule.common.rulebasebean.Fact;
import com.tansun.easycare.rule.common.rulebasebean.RuleCollection;
import com.tansun.easycare.rule.common.rulebasebean.RuleItem;
import com.tansun.easycare.rule.common.service.impl.RuleBaseServiceImpl;
import com.tansun.easycare.rule.exception.BizException;
import com.tansun.easycare.rule.referencedata.entity.RuleReferenceData;
import com.tansun.easycare.rule.referencedata.service.RuleReferenceDataService;
import com.tansun.easycare.rule.rulemange.entity.RuleManage;
import com.tansun.easycare.rule.rulemange.service.RuleManageService;
import com.tansun.easycare.rule.ruleversion.entity.RuleVersioninfo;
import com.tansun.easycare.rule.ruleversion.service.RuleVersioninfoService;
import com.tansun.easycare.rule.table.dao.RuleDecisiontableDetailDao;
import com.tansun.easycare.rule.table.entity.RuleDecisiontableDetail;
import com.tansun.easycare.rule.table.evaluationindex.model.EvaluationIndexItem;
import com.tansun.easycare.rule.table.evaluationindex.model.IndexEntity;
import com.tansun.easycare.rule.table.evaluationindex.service.EvaluationIndexService;
import com.tansun.easycare.rule.utils.DroolsUtils;
import com.tansun.rule.common.RuleModelTypeEnum;

@Service
public class EvaluationIndexServiceImpl extends RuleBaseServiceImpl<RuleDecisiontableDetailDao, RuleDecisiontableDetail> implements EvaluationIndexService {

    @Autowired
    private RuleManageService ruleManageService;
    @Autowired
    private RuleVersioninfoService ruleVersioninfoService;

    @Autowired
    private RuleReferenceDataService ruleReferenceDataService;

    @Override
    public void saveOrUpdate(IndexEntity indexEntity) throws BizException {

        RuleManage ruleManage = indexEntity.getIndexModel();
        ruleManage.setStatus("1");
        ruleManage.setModelType(RuleModelTypeEnum.EvaluationIndex.getCode());
        ruleManage = ruleManageService.saveOrUpdate(ruleManage);

        List<EvaluationIndexItem> indexList = indexEntity.getIndexInfoList();
        String status = ruleManage.getStatus();
        String context = writeDrl(indexEntity.getIndexModel(), indexList);
        Map<String, RuleReferenceData> dataMap = new HashMap();
        if (!"0".equals(status) && !"2".equals(status)) {
            RuleVersioninfo ruleVersioninfo = new RuleVersioninfo();
            ruleVersioninfo.init(ruleManage, context);
            this.ruleVersioninfoService.save(ruleVersioninfo);
            //保存明细
            int row = 0; //行
            int col = 0; //列
            List<EvaluationIndexItem> iList = null;
            RuleDecisiontableDetail dtDetail = null;
            List<RuleDecisiontableDetail> reList = new ArrayList<RuleDecisiontableDetail>();
            for (EvaluationIndexItem indexItem : indexList) {
                col = 0;
                iList = indexItem.getList();
                dtDetail = new RuleDecisiontableDetail();
                dtDetail.setColumnNo(col);
                dtDetail.setRowNo(row);
                dtDetail.setContentType("in");

                dtDetail.setNamecn(indexItem.getNameCN());
                dtDetail.setNameen(indexItem.getNameEN());
                dtDetail.setModelType(ruleManage.getModelType());
                dtDetail.setProjectCode(ruleManage.getProjectCode());
                try {
                    BeanUtils.copyProperties(dtDetail, indexItem);
                } catch (Exception e) {
                    throw new BizException(e, "E-000000");

                }
                dtDetail.setManageId(ruleManage.getId());
                dtDetail.setVersion(ruleManage.getVersion());
                dtDetail.setPosition(indexItem.getPosition());
                col = 1;//1列
                reList.add(dtDetail);
                this.ruleReferenceDataService.collectTableDetail(dtDetail, dataMap, ruleManage);
                for (EvaluationIndexItem cItem : iList) {
                    dtDetail = new RuleDecisiontableDetail();
                    dtDetail.setColumnNo(col);
                    dtDetail.setClassName(cItem.getClassName());
                    //dtDetail.setContentType(cItem.getContentType());
                    dtDetail.setControlValue(cItem.getControlValue());

                    dtDetail.setDataType(cItem.getDataType());
                    dtDetail.setDefaultValue(cItem.getDefaultValue());
                    dtDetail.setDomain(cItem.getDomain());
                    //dtDetail.setFormula(dTableItem.get);
                    dtDetail.setIsDerives(cItem.getIsDerives());
                    dtDetail.setNamecn(cItem.getNameCN());
                    dtDetail.setNameen(cItem.getNameEN());
                    dtDetail.setModelType(ruleManage.getModelType());
                    //dtDetail.s
                    dtDetail.setProjectCode(ruleManage.getProjectCode());
                    dtDetail.setManageId(ruleManage.getId());
                    dtDetail.setVersion(ruleManage.getVersion());

                    dtDetail.setRowNo(row);
                    dtDetail.setContentType("out");
                    dtDetail.setTabId(cItem.getTabId());
                    dtDetail.setPosition(cItem.getPosition());
                    dtDetail.setPattern(cItem.getPattern());
                    col++;
                    reList.add(dtDetail);
                    this.ruleReferenceDataService.collectTableDetail(dtDetail, dataMap, ruleManage);
                }
                row++;
            }
            this.insertBatch(reList);
            this.ruleReferenceDataService.saveReferenceData(dataMap);
        }
    }

    private String writeDrl(RuleManage index, List<EvaluationIndexItem> indexItem) throws BizException {
        if (indexItem == null || indexItem.size() == 0)
            return null;
        RuleCollection ruleCollection = new RuleCollection();
        ruleCollection.setDrlName(index.getCode());
        ruleCollection.setObjName(index.getName());
        ruleCollection.setContentType(RuleCollection.RULEINDEX);
        ruleCollection.setVersion(index.getVersion());
        //生成动作组  优先级从1开始递减
        int priority = 1;
        for (EvaluationIndexItem item : indexItem) {
            String randomIdString = com.tansun.rule.utils.StringUtils.GenerateRandom(6);
            item.setTabId(randomIdString);
            String ruleName = "index_" + randomIdString;
            String whenStr = generateDrl(item, "when");
            String thenStr = "";
            for (EvaluationIndexItem child : item.getList()) {
                thenStr += generateDrl(child, "then");
            }
            RuleItem ruleItem = getCustomRule(ruleName, priority, whenStr, thenStr);
            ruleCollection.getListItem().add(ruleItem);
            priority--;
        }
        try {
            return DroolsUtils.convert2Drl(ruleCollection);
        } catch (Exception e) {
            throw new BizException(e, "");

        }
    }

    private String generateDrl(EvaluationIndexItem item, String type) {
        String retStr = "";
        String vals = item.getControlValue();
        String dataType = item.getDataType();
        if (type.equals("when")) {
            retStr = "this[\"" + item.getClassName() + "\"][\"" + item.getNameEN() + "\"]";
            if (!StringUtils.isEmpty(item.getPosition())) {
                retStr += ".get(" + item.getPosition() + ")";
            }
            if (item.getDataType().equals("String")) {
                if (!StringUtils.isEmpty(item.getDomain()) && item.getControlValue().indexOf("[") >= 0) {
                    vals = item.getControlValue().substring(1, item.getControlValue().length() - 1);
                    retStr += " in (" + vals + ") ";
                } else {

                    retStr += "== " + "\"" + item.getControlValue() + "\"";
                }
            } else if (item.getDataType().equals("Boolean")) {
                retStr = retStr + "==" + (item.getControlValue().equals("1") ? "true" : "false");
            } else {
                String leftOpt = item.getLowerOpt();
                String rightOpt = item.getUpperOpt();
                if (vals.indexOf(",") < 0) return "";
                String[] valArr = vals.split(",");
                if (dataType.equals("Date")) {
                    for (int i = 0; i < valArr.length; i++) {
                        valArr[i] = "\"" + valArr[i] + "\"";
                    }
                }
                String expression = retStr;
                if (!StringUtils.isEmpty(leftOpt) && valArr[0].length() > 0) {
                    if (leftOpt.equals("[")) {
                        retStr = expression + ">=" + valArr[0];
                    } else {
                        retStr = expression + ">" + valArr[0];
                    }
                } else {
                    retStr = "";
                }
                if (valArr.length == 2) {
                    if (!StringUtils.isEmpty(retStr))
                        retStr += " && ";
                    if (rightOpt.equals("]")) {
                        retStr += expression + "<=" + valArr[1];
                    } else {
                        retStr += expression + "<" + valArr[1];
                    }
                }

//				if(vals.indexOf(",")<0)
//					return "";
//				String[] valArr = item.getControlValue().split(",");
//				String expression = retStr;
//				if(item.getLowerOpt().equals("[")){
//					retStr = expression + ">="+valArr[0];
//				}else{
//					retStr = expression + ">"+valArr[0];
//				}
//				if(valArr.length==2){
//					retStr += " && ";
//					if(item.getUpperOpt().equals("]")){
//						retStr += expression+"<="+valArr[1];
//					}else{
//						retStr += expression+"<"+valArr[1];
//					}
//				}
            }
        } else if (type.equals("then")) {
            retStr = "ruleHelper.setValue";
            if ("List".equals(item.getCollection())) {
                retStr = "ruleHelper.insertValue";
            }
            retStr += "($insertMap,\"" + item.getClassName() + "." + item.getNameEN() + "\",\"" + item.getControlValue() + "\");\n";
        }
        return retStr;
    }

    private RuleItem getCustomRule(String ruleName, int priority, String factStr, String actionStr) {
        RuleItem rule = new RuleItem();
        rule.setEnabled("on");
        rule.setRuleName(ruleName);
        rule.setSalience(priority);
        DWhen dWhen = new DWhen();
        Fact fact = new Fact();
        fact.setContent(factStr);
        dWhen.setFirstFact(fact);
        DThen dThen = new DThen();
        Action action = new Action();
        action.setContent(actionStr);
        dThen.getListAction().add(action);
        rule.setdWhen(dWhen);
        rule.setdThen(dThen);
        return rule;
    }

    @Override
    public List<EvaluationIndexItem> findEvaluationIndexItemByIndexId(String indexId, String version) throws BizException {

        RuleDecisiontableDetail decisiontableDetail = new RuleDecisiontableDetail();
        decisiontableDetail.setManageId(indexId);
        decisiontableDetail.setVersion(version);
        List<RuleDecisiontableDetail> list = this.dao.findList(decisiontableDetail);
        if (list == null) return null;
        List<EvaluationIndexItem> resultList = new ArrayList();
        EvaluationIndexItem indexItem = null;
        EvaluationIndexItem childItem = null;
        int iCol = 0; //列
        for (RuleDecisiontableDetail tableDetail : list) { //排序列表
            iCol = tableDetail.getColumnNo();
            if (iCol == 0) {
                indexItem = new EvaluationIndexItem();
                indexItem.setList(new ArrayList<EvaluationIndexItem>());
                try {
                    BeanUtils.copyProperties(indexItem, tableDetail);
                    indexItem.setNameCN(tableDetail.getNamecn());
                    indexItem.setNameEN(tableDetail.getNameen());
                } catch (Exception e) {
                    throw new BizException(e, "E-000000");

                }
                resultList.add(indexItem);
            } else {
                childItem = new EvaluationIndexItem();
                try {
                    BeanUtils.copyProperties(childItem, tableDetail);
                    childItem.setNameCN(tableDetail.getNamecn());
                    childItem.setNameEN(tableDetail.getNameen());
                } catch (Exception e) {
                    throw new BizException(e, "E-000000");

                }
                if (indexItem.getList() != null)
                    indexItem.getList().add(childItem);
            }
        }
        return resultList;
    }
}
